"""
股票图表应用程序主类
整合所有模块，提供完整的K线图和成交量图功能
"""

import sys
from PyQt5.QtWidgets import QApplication
import pyqtgraph as pg
from .config import config, flags
from .data_loader import DataLoader
from .candlestick_chart import CandlestickChart
from .volume_chart import VolumeChart
from .mouse_interaction import MouseInteraction, MouseInteractionManager
from .moving_average import MovingAverageManager


class StockChartApp:
    """股票图表应用程序主类"""
    
    def __init__(self, window_title: str = "K线图与成交量 - PyQtGraph"):
        """
        初始化应用程序
        
        Args:
            window_title: 窗口标题
        """
        self.window_title = window_title
        self.app: Optional[QApplication] = None
        self.win: Optional[pg.GraphicsLayoutWidget] = None
        
        # 初始化各个组件
        self.data_loader = DataLoader()
        self.kline_chart: Optional[CandlestickChart] = None
        self.volume_chart: Optional[VolumeChart] = None
        self.mouse_manager = MouseInteractionManager()
        
        # 图表控件
        self.kline_plot: Optional[pg.PlotWidget] = None
        self.volume_plot: Optional[pg.PlotWidget] = None
    
    def initialize_app(self):
        """初始化应用程序"""
        self.app = QApplication(sys.argv)
        self.win = pg.GraphicsLayoutWidget(show=True, title=self.window_title)
        self.win.resize(1000, 800)
        
        # 创建图表控件
        self._create_plots()
        
        # 初始化图表组件
        self._initialize_charts()
    
    def _create_plots(self):
        """创建绘图控件"""
        # 上面的K线图
        self.kline_plot = self.win.addPlot(title="K线图", row=0, col=0)
        
        # 下面的成交量图
        self.volume_plot = self.win.addPlot(title="成交量", row=1, col=0)
    
    def _initialize_charts(self):
        """初始化图表组件"""
        if self.kline_plot is None or self.volume_plot is None:
            raise ValueError("绘图控件尚未创建")
        
        # 初始化K线图
        self.kline_chart = CandlestickChart(self.kline_plot)

        # 初始化移动平均线
        self.moving_average_manager = MovingAverageManager(self.kline_plot)
        
        # 初始化成交量图
        self.volume_chart = VolumeChart(self.volume_plot)
        
        # 链接X轴
        self.kline_chart.link_x_axis(self.volume_plot)
    
    def load_data(self, file_path: str, date_format: str = '%Y%m%d'):
        """
        加载股票数据
        
        Args:
            file_path: CSV文件路径
            date_format: 日期格式
        """
        # 加载数据
        self.data_loader.load_from_csv(file_path, date_format)
        
        # 更新图表
        self._update_charts()
        
        # 设置鼠标交互
        self._setup_mouse_interactions()
    
    def _update_charts(self):
        """更新图表数据"""
        if self.data_loader.get_data() is None:
            raise ValueError("数据尚未加载")
        
        # 获取K线数据
        candlestick_data = self.data_loader.get_candlestick_data()
        self.kline_chart.update_data(candlestick_data)

        # 设置移动平均线数据
        self.moving_average_manager.set_data(self.data_loader.get_data())
        self.moving_average_manager.update_moving_averages(config.DEFAULT_MA_PERIODS,config.MA_COLORS)
        
        # 获取成交量数据
        volume_x, volume_heights, volume_colors = self.data_loader.get_volume_data()
        self.volume_chart.update_data(volume_x, volume_heights, volume_colors)
        
        # 设置价格和成交量范围
        self._set_ranges()
        
        # 设置X轴范围和日期刻度
        self._set_axes()
    
    def _set_ranges(self):
        """设置图表范围"""
        # K线图价格范围
        min_price, max_price = self.data_loader.get_price_range()
        self.kline_chart.set_price_range(min_price, max_price)
        
        # 成交量范围
        min_volume, max_volume = self.data_loader.get_volume_range()
        self.volume_chart.set_volume_range(min_volume, max_volume)
        
        # 将成交量按价格比例缩放
        self.volume_chart.scale_volume_to_price(max_volume, max_price)
    
    def _set_axes(self):
        """设置坐标轴"""
        data_length = len(self.data_loader.get_data())
        
        # 设置X轴范围
        self.kline_chart.set_x_range(0, data_length - 1)
        self.volume_chart.set_x_range(0, data_length - 1)
        
        # 设置日期刻度
        date_ticks = self.data_loader.get_date_ticks(config.MAX_DATE_TICKS)
        self.kline_chart.set_date_ticks(date_ticks)
        self.volume_chart.set_date_ticks(date_ticks)
    
    def _setup_mouse_interactions(self):
        """设置鼠标交互"""
        # K线图鼠标交互
        kline_interaction = MouseInteraction(
            self.kline_plot, 
            self.data_loader, 
            "kline"
        )
        self.mouse_manager.add_interaction(kline_interaction)
        
        # 成交量图鼠标交互
        volume_interaction = MouseInteraction(
            self.volume_plot, 
            self.data_loader, 
            "volume"
        )
        self.mouse_manager.add_interaction(volume_interaction)
    
    def run(self):
        """运行应用程序"""
        if self.app is None:
            raise ValueError("应用程序尚未初始化")
        
        sys.exit(self.app.exec_())
    
    def get_window(self) -> pg.GraphicsLayoutWidget:
        """获取主窗口"""
        return self.win
    
    def get_data_loader(self) -> DataLoader:
        """获取数据加载器"""
        return self.data_loader
    
    def get_kline_chart(self) -> CandlestickChart:
        """获取K线图"""
        return self.kline_chart
    
    def get_volume_chart(self) -> VolumeChart:
        """获取成交量图"""
        return self.volume_chart
    
    def cleanup(self):
        """清理资源"""
        self.mouse_manager.disconnect_all()
    
    def __del__(self):
        """析构函数"""
        self.cleanup()


# 便捷函数
def create_stock_chart_app(file_path: str, window_title: str = "K线图与成交量 - PyQtGraph") -> StockChartApp:
    """
    创建股票图表应用程序的便捷函数
    
    Args:
        file_path: CSV文件路径
        window_title: 窗口标题
        
    Returns:
        配置好的应用程序实例
    """
    app = StockChartApp(window_title)
    app.initialize_app()
    app.load_data(file_path)
    return app


def run_stock_chart(file_path: str, window_title: str = "K线图与成交量 - PyQtGraph"):
    """
    运行股票图表的便捷函数
    
    Args:
        file_path: CSV文件路径
        window_title: 窗口标题
    """
    app = create_stock_chart_app(file_path, window_title)
    try:
        app.run()
    finally:
        app.cleanup()
